package io.nutz.nutzsite.module.exam.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import io.nutz.nutzsite.common.utils.ShiroUtil;
import io.nutz.nutzsite.module.exam.models.*;
import io.nutz.nutzsite.module.exam.services.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.POST;
import org.nutz.mvc.annotation.Param;
import org.nutz.plugins.slog.annotation.Slog;

import io.nutz.nutzsite.common.base.Globals;
import io.nutz.nutzsite.common.base.Result;
import io.nutz.nutzsite.common.caffeine.MyCache;
import io.nutz.nutzsite.common.exception.ErrorException;
import io.nutz.nutzsite.common.page.TableDataInfo;
import io.nutz.nutzsite.common.socket.OJSocket;
import io.nutz.nutzsite.common.utils.DateUtils;
import io.nutz.nutzsite.common.utils.ShiroUtils;
import io.nutz.nutzsite.common.utils.StringUtils;
import io.nutz.nutzsite.module.acm.models.Solution;
import io.nutz.nutzsite.module.acm.models.SolutionSource;
import io.nutz.nutzsite.module.acm.services.SolutionService;
import io.nutz.nutzsite.module.acm.services.SolutionSourceService;
import io.nutz.nutzsite.module.sys.models.Menu;
import io.nutz.nutzsite.module.sys.models.Mytask;
import io.nutz.nutzsite.module.sys.models.Role;
import io.nutz.nutzsite.module.sys.models.User;
import io.nutz.nutzsite.module.sys.services.MenuService;
import io.nutz.nutzsite.module.sys.services.MytaskService;
import io.nutz.nutzsite.module.sys.services.RoleService;
import io.nutz.nutzsite.module.sys.services.UserService;
/**
 * 排考抽题 信息操作处理
 * 
 * @author lrw
 * @date 2020-04-08
 */
@IocBean
@At("/exam/exarrange")
public class ExarrangeController {
	private static final Log log = Logs.get();

	@Inject
	private ExarrangeService exarrangeService;
	@Inject
	private PaperdefService paperdefService;
	@Inject
	private PapertplService papertplService;
	@Inject
	private RoleService roleService;
	@Inject
	private UserService userService;
	@Inject
	private QuestionService questionService;
	@Inject
	private QtypeService qtypeService;
	@Inject
	private ScoresService scoresService;
	@Inject
    private MenuService menuService;
	 @Inject
	MytaskService mytaskService;
	 @Inject
		private SolutionService solutionService;
	 @Inject
		private SolutionSourceService  solutionSourceService;
	 @Inject
	 private PctimeService pctimeService;
	@Inject
	private RoomService roomService;


	@RequiresPermissions("exam:exarrange:view")
	@At("/?")
	@Ok("th:/exam/exarrange/exarrange.html")
	public void index(String id,HttpServletRequest req) {
		req.setAttribute("ksid", id);
	}
	
	//@RequiresPermissions("exam:exarrange:kcmgr")
	@At("/kcmgr")//?
	@Ok("th:/exam/exarrange/kcmgr.html")
	public void kcmgr(HttpServletRequest req) {//String id,
		User user = ShiroUtils.getSysUser();
		List<Menu> menuList = menuService.getMenuList2(user.getId());
        String perms="";
        for(Menu menu:menuList){
        	if(!menu.getPerms().equals("")) perms+=menu.getPerms()+",";
        }
        req.setAttribute("perms", perms);
		/*req.setAttribute("ksid", id);
		Paperdef p= paperdefService.fetch(id);
		req.setAttribute("ksname", p.getName());*/
		req.setAttribute("now0", DateUtils.getDateTime());

		List<Pctime> list=pctimeService.query();
		req.setAttribute("pctimes", list);
		List<Room> list2=roomService.query(Cnd.where("status","=",1));
		req.setAttribute("ksrooms", list2);
		user =userService.fetchLinks(user,"roles");
		List<Role> rolelist=user.getRoles();
		String roles=",";
		for(Role role:rolelist) roles+=role.getId()+",";
		user.setRoleIds(roles);
		req.setAttribute("user", user);

	}
	@RequiresPermissions("exam:exarrange:kcmgr")
	@At("/doedit/?")
	@Ok("json")
	@Slog(tag="监考", after="监考操作${args[0]}")
	public Object doedit(Integer n,@Param("ids")String ids,
			@Param("minnum")int minnum,HttpServletRequest req) {
		String str="";
		try{
			String[] id=ids.split(",");
			//Exarrange exarr=exarrangeService.fetch(Integer.parseInt(id[0]));
			List<Exarrange> exarrs=exarrangeService.query(Cnd.where("id","in",id));
			Exarrange exarr=exarrs.get(0);
			String ksid=exarr.getKsid();
			Paperdef paperdef=paperdefService.fetch(ksid);
			int duration=paperdef.getDuration();
			switch(n){
			case 1://密码
			{
				User user=userService.fetch(exarr.getUid());
				String cardid=user.getCardid();
				str=cardid.substring(cardid.length()-6);// .substring(12);//不适合特种身份证号码，如香港
				break;
			}
			case 2://换机
			{
				//exarr.setLoginip2("");
				//exarrangeService.updateIgnoreNull(exarr);
				exarrangeService.update(Chain.make("loginip2", ""), Cnd.where("id","in",id));
				exarrangeService.update(Chain.make("macaddr", ""), Cnd.where("id","in",id));
				str="已设置成功，考生重新登录考试";
				break;}
			case 3://重考
			{
				/*scoresService.delete(Cnd.where("ksid","=",exarr.getKsid()).and("uid","=",exarr.getUid()));
				NutMap oldmap=Json.fromJson(Paper.class,exarr.getPaperdata()).getQtidmap();
				
				exarrangeService._delete(exarr);
				makepaper(exarr.getUid(),oldmap);*/
				ArrayList<String> uids = new ArrayList<String>();
				for (Exarrange ex : exarrs) {
					uids.add(ex.getUid());
				}
				scoresService.delete(Cnd.where("ksid", "=", ksid).and("uid", "in", uids));
				//不重新发卷
				exarrangeService.update(Chain.make//("paperdata", null).add("kmid", null).add("ksid", null).add("starttime", null).add("endtime", null).add
								("signintime", null).add("loginip2", null)
								.add("udtime", 0)
								.add("jjtime", null).add("status", 0),
						Cnd.where("id", "in", id));
				mytaskService.update(Chain.make("status", 0), Cnd.where("ksid", "=", ksid).and("uid", "in", uids));
				str = "已设置成功，考生重新登录考试";
				break;
			}
			case 4://延时
			{
				for (Exarrange ex : exarrs) {
					int udtime = ex.getUdtime();
					String uid=ex.getUid();
					//中场，直接延时；交卷时，重新登录不能进入（截止时间到，用时也到），除了延时还要延长截止时间（考试安排和任务2表）

					if (udtime + minnum<=duration) {//中场，延时后不会超出截止时间
						ex.setUdtime(udtime - minnum);
						//Date date= ex.getSignintime();
						//date=DateUtils.addsubDate(date, minnum);
						//ex.setSignintime(date);
						exarrangeService.updateIgnoreNull(ex);
					} else if (udtime < minnum){//开始不久，重新计时
						ex.setUdtime(0);
						exarrangeService.updateIgnoreNull(ex);
					} else if (udtime + minnum>duration) {//快结束或交卷时，延时后会超出截止时间
						Date enddate= ex.getEndtime();
						enddate=DateUtils.addsubDate(enddate, minnum);
						exarrangeService.update(Chain.make("endtime", enddate).add("udtime", duration-minnum),
								Cnd.where("id", "=", ex.getId()));
						mytaskService.update(Chain.make("endtime", enddate), Cnd.where("ksid", "=", ksid).and("uid", "in", uid));

					}
				}
				str = "最多已补时" + minnum + "分钟";
				break;
			}
			}	
			return Result.success(str);
		}catch(Exception e){
			return Result.error(e.getMessage());
		}
	}
	/**
	 * 查询排考抽题列表
	 */
	@RequiresPermissions("exam:exarrange:list")
	@At
	@Ok("json")
	public Object list(@Param("pageNum")int pageNum,
					   @Param("pageSize")int pageSize,
					   @Param("ksid") String ksid,
					   @Param("ismiss") String ismiss,
					   @Param("uid") String uid,
					   @Param("orderByColumn") String orderByColumn,
					   @Param("isAsc") String isAsc,
					   HttpServletRequest req) {
		Cnd cnd = Cnd.NEW();
		if (!Strings.isBlank(ksid)){
			cnd.and("ksid", "=", ksid);
		}
		if (!Strings.isBlank(uid)) {
            cnd.and("uid", "like", "%" + uid + "%");
        }
		/*if (!Strings.isBlank(ismiss) && ismiss.equals("1")){
			cnd.and("signintime","=",null);
		}else  cnd.andNot("signintime","=",null);*/
		//return exarrangeService.tableList(pageNum,pageSize,cnd,orderByColumn,isAsc,"paperdef");
		TableDataInfo tdi=exarrangeService.tableList(pageNum,pageSize,cnd,orderByColumn,isAsc,"paperdef");
		int t1=exarrangeService.count(Cnd.where("ksid", "=", ksid).and("status","=",0));
		int t2=exarrangeService.count(Cnd.where("ksid", "=", ksid).and("status","=",4));
		int t3=exarrangeService.count(Cnd.where("ksid", "=", ksid).and("status","=",8));
		int t4=exarrangeService.count(Cnd.where("ksid", "=", ksid).and("status","=",9));

		tdi.setT1(t1);
		tdi.setT2(t2);
		tdi.setT3(t3);
		tdi.setT4(t4);
		
		return tdi;
	}
	@At
	@Ok("json")
	public Object listip(@Param("pageNum")int pageNum,
					   @Param("pageSize")int pageSize,
					   //@Param("ksid") String ksid,
					   @Param("ismiss") String ismiss,
					   @Param("uid") String uid,
					   @Param("orderByColumn") String orderByColumn,
					   @Param("isAsc") String isAsc,
					   @Param("ip") String ip,@Param("pc") int pc,
					   HttpServletRequest req) {
		Cnd cnd = Cnd.NEW();
		/*if (!Strings.isBlank(ksid)){
			cnd.and("ksid", "=", ksid);
		}*/
		if (!Strings.isBlank(uid)) {
            cnd.and("uid", "like", "%" + uid + "%");
        }
		/*if (!Strings.isBlank(ismiss) && ismiss.equals("1")){
			cnd.and("signintime","=",null);
		}else  cnd.andNot("signintime","=",null);*/
		//return exarrangeService.tableList(pageNum,pageSize,cnd,orderByColumn,isAsc,"paperdef");
		User user=ShiroUtils.getSysUser();
		User u =userService.fetchLinks(user,"roles");
		String myip=u.getLoginIp();
		List<Role> rolelist=user.getRoles();
		String roles=",";
		for(Role role:rolelist) roles+=role.getId()+",";
		if(roles.contains(",1,") && ip!=null)
			myip=ip;
		//仅用于指定考场的监考
		cnd.and("pc","=",pc).and("loginip","=",myip);
		TableDataInfo tdi=exarrangeService.tableList(pageNum,pageSize,cnd,orderByColumn,isAsc,"user");
		/*int t1=exarrangeService.count(Cnd.where("ksid", "=", ksid).and("pc","=",pc).and("loginip","=",myip).and("status","=",0));
		int t2=exarrangeService.count(Cnd.where("ksid", "=", ksid).and("pc","=",pc).and("loginip","=",myip).and("status","=",4));
		int t3=exarrangeService.count(Cnd.where("ksid", "=", ksid).and("pc","=",pc).and("loginip","=",myip).and("status","=",8));
		int t4=exarrangeService.count(Cnd.where("ksid", "=", ksid).and("pc","=",pc).and("loginip","=",myip).and("status","=",9));
*/
		int t1=exarrangeService.count(Cnd.where("pc","=",pc).and("loginip","=",myip).and("status","=",0));
		int t2=exarrangeService.count(Cnd.where("pc","=",pc).and("loginip","=",myip).and("status","=",4));
		int t3=exarrangeService.count(Cnd.where("pc","=",pc).and("loginip","=",myip).and("status","=",8));
		int t4=exarrangeService.count(Cnd.where("pc","=",pc).and("loginip","=",myip).and("status","=",9));

		tdi.setT1(t1);
		tdi.setT2(t2);
		tdi.setT3(t3);
		tdi.setT4(t4);
		
		return tdi;
	}	
	/**
	 * 查询排考抽题列表
	 */
	@RequiresPermissions("exam:exarrange:list")
	@At
	@Ok("json")
	public Object myks(@Param("pageNum")int pageNum,
					   @Param("pageSize")int pageSize,
					   @Param("orderByColumn") String orderByColumn,
					   @Param("isAsc") String isAsc,
					   HttpServletRequest req) {
		Cnd cnd = Cnd.NEW();		
        cnd.and("uid", "=", ShiroUtils.getSysUserId());
		return exarrangeService.tableList(pageNum,pageSize,cnd,orderByColumn,isAsc,"paperdef");
	}
	/**
	 * 仅适合只开放一个考试且登录抽题的情况
	 * @param pageNum
	 * @param pageSize
	 * @param orderByColumn
	 * @param isAsc
	 * @param req
	 * @return
	 */
	@RequiresPermissions("exam:exarrange:list")
	@At
	@Ok("json")
	public Object mylist(@Param("pageNum")int pageNum,
					   @Param("pageSize")int pageSize,
					   @Param("orderByColumn") String orderByColumn,
					   @Param("isAsc") String isAsc,
					   HttpServletRequest req) {
		Cnd cnd = Cnd.NEW();
		cnd.and("status","=",1);
		return paperdefService.tableList(pageNum,pageSize,cnd,orderByColumn,isAsc,null);
	}

	/**
	 * 新增排考抽题
	 */
	@At("/add/?")
	@Ok("th:/exam/exarrange/add.html")
	public void add(String id, HttpServletRequest req) {
		Paperdef paperdef= paperdefService.fetch(id);
		req.setAttribute("paperdef", paperdef);
		req.setAttribute("ksid", id);
	}
	

	@At
	@POST
	@Ok("json")
	//@RequiresPermissions("exam:exarrange:edit")
	public Object check(@Param("id")String id,HttpServletRequest req){
		try{
			User user=ShiroUtils.getSysUser();
			String uid=user.getId();
			Cnd cnd=Cnd.NEW();
			cnd.and("ksid","=",id).and("uid","=",uid);
			Exarrange exarr=exarrangeService.fetch(cnd);
			/*Mytask mytask=mytaskService.fetch(cnd);
			String pretask=mytask.getPretask();
			if(pretask!=null && !pretask.equals("")){
				Mytask mytask2=mytaskService.fetch(Cnd.where("ksid","=",pretask).and("uid","=",uid));
				if(mytask2.getStatus()!=2){
					return Result.error("必须先完成前置任务（编号："+pretask+"）");
				}
			}*/
			if(exarr==null || exarr.getPaperdata()==""){//首次进入，无题则抽题
				makepaper(uid,null);
			}
			Thread.sleep(2000);
			exarr=exarrangeService.fetch(Cnd.where("ksid","=",id).and("uid","=",uid));
			//部分手机，重新进入时ip变化？？
			String ip2=Lang.getIP(req);
			String eroomip=exarr.getLoginip();
			//String ip=exarr.getLoginip2();			
			/*if(ip!=null && ip.length()>0 && !ip.equals(ip2))//换机了
				return Result.error("换电脑需要经过监考老师批准！");*/
			Paperdef paperdef=paperdefService.fetch(Cnd.where("id","=",id));
			int kstype=paperdef.getKstype();
			boolean restip=paperdef.isRestip();
			if(kstype==1 && restip==true && !ip2.equals(eroomip))
				return Result.error("你只能在指定的考场("+exarr.getKch()+")登录FCRE");
			String mac=exarr.getMacaddr();
			String mac0=user.getMacaddr();
			if(kstype==1 && restip==true && mac!=null && mac.length()>=17 && !mac.equals(mac0))//换机了
				return Result.error("换机需要经过监考老师批准！");
			//else if(mac==null || mac.length()<17) {exarr.setMacaddr(mac0);exarrangeService.updateIgnoreNull(exarr);}
			if(kstype==1 && exarr.getStatus()==8)
				return Result.error("你已经交卷了，重考须经监考老师批准！");
			if(exarr.getStarttime().getTime()>(new Date()).getTime())
				return Result.error("本次考试还没开始！");
			if(exarr.getEndtime().getTime()<(new Date()).getTime())
				return Result.error("本次考试已经结束了！");
			
			return Result.success("exam/exarrange/joinexam/");
		}catch(Exception e){
			return Result.error(e.getMessage());
		}
	}
	/**
	 * 新增排考抽题
	 */
	@RequiresPermissions("exam:exarrange:view")
	@At("/joinexam/?")
	@Ok("re")
	@Slog(tag="进入考试", after="考生进入试卷 id=${args[0]}")
	public String joinexam(String id, HttpServletRequest req) {
		User user=ShiroUtils.getSysUser();
		Exarrange exarr=exarrangeService.fetch(Cnd.where("ksid","=",id).and("uid","=",user.getId()));
		if(exarr.getStatus()!=8) exarr.setStatus(4);
		else return "th:/exam/exarrange/ksing2.html";
		String ip2=Lang.getIP(req);
		if(exarr.getSignintime()==null) {//首次进入考试
			exarr.setSignintime(new Date());
			req.setAttribute("first", 1);
		}else req.setAttribute("first", 0);
		exarr.setLoginip2(ip2);
		exarr.setMacaddr(user.getMacaddr());
		int kmid=exarr.getKmid();
		int langid=0;
		switch(kmid){
			case 24:langid=3;break;
			case 66:langid=9;break;
			case 28:langid=5;break;
			case 61:langid=4;break;
		}
		String paperdata=exarr.getPaperdata();
		exarrangeService.updateIgnoreNull(exarr);

		req.setAttribute("id", exarr.getId());
		req.setAttribute("now0", DateUtils.getDateTime());
		
		Paper paper=Json.fromJson(Paper.class,paperdata);
		paper.setUid(exarr.getUid());
		
		NutMap qtidmap=paper.getQtidmap();
		NutMap qtidmap2=new NutMap();
		String ofile="";
		for(String key : qtidmap.keySet()){
			NutMap map=(NutMap)qtidmap.get(key);
			//NutMap idscoremap=(NutMap)map.get("idscore");
			//======================================================
			String qids=map.getString("qids");
			if(Integer.parseInt(key)>=5 && Integer.parseInt(key)<=15){
				if(ofile.length()>0) ofile+="|";
				ofile+=key+"|"+qids;
			}
			String[] qscores=map.getString("qscores").split(",");
			List<Question> qlist=questionService.query("^(id|qtid|name|ansA|ansB|ansC|ansD)$",Cnd.where("id","in",qids).asc("instr(',"+qids+",',concat(',',id,','))"));
			int i=0;
			for(Question question:qlist){
				//question.setQscore(Float.parseFloat( idscoremap.get(question.getId()+"").toString()));
				question.setQscore(Float.parseFloat( qscores[i++]));
			}
			NutMap map2=new NutMap();
			map2.addv("qlist", qlist);
			map2.addv("qname", map.getString("qname"));
			map2.addv("qscore", map.getFloat("qscore"));			
			//=========================================================
			qtidmap2.addv(key, map2);
		}
		qtidmap.clear();
		paper.setQtidmap(null);
		paper.setQtidmap(qtidmap2);
		req.setAttribute("ofile",exarr.getKmid()+"|"+ ofile);
		req.setAttribute("paper", paper);
		req.setAttribute("user", user);
		req.setAttribute("langid", langid);
		req.setAttribute("kmid", kmid);
		Paperdef paperdef=paperdefService.fetch(id);
		int kstype=paperdef.getKstype();
		req.setAttribute("kstype", kstype);
		return "th:/exam/exarrange/ksing.html";
	}
	
	@At("/getLeftTime/?")
	@POST
	@Ok("json")
	//@RequiresPermissions("exam:exarrange:edit")
	public Object getLeftTime(Integer id,HttpServletRequest req){
		Exarrange exarr=exarrangeService.fetch(id);
		if(exarr.getStatus()==8)return Result.success("-8");
		/*Date sntime=exarr.getSignintime();
		Date now=new Date();
		int d=new Double(DateUtils.getDistanceOfTwoDate(sntime, now, "m")).intValue();
		exarr.setUdtime(d);
		exarrangeService.updateIgnoreNull(exarr);*/
		
		Paperdef paperdef =paperdefService.fetch(exarr.getKsid());

		return Result.success((paperdef.getDuration()- exarr.getUdtime())+"");
	}

	/**
	 * 新增排考抽题
	 */
	@At("/makep/?")
	@Ok("th:/exam/exarrange/add.html")
	public void makep(String id, HttpServletRequest req) {
		req.setAttribute("ksid", id);
		List<Role> roles = roleService.query(Cnd.where("status", "=", false).and("del_flag", "=", false));
        req.setAttribute("roles", roles);
        Paperdef paperdef= paperdefService.fetch(id);
		req.setAttribute("paperdef", paperdef);
	}
	/**
	 * 新增保存排考抽题
	 */
	@At
	@POST
	@Ok("json")
	@RequiresPermissions("exam:exarrange:add")
	@Slog(tag="生成试卷", after="新增保存排考抽题 id=${args[0].id}")
	public Object addDo(@Param("..") Exarrange exarrange,
			@Param("ksuser") String ksuser,
			@Param("role") String role,
			HttpServletRequest req) {
		try {
			//=========找考生========================================
			Cnd cnd=Cnd.NEW();
			if(ksuser.length()>0){
				ksuser=StringUtils.StringToString(ksuser);
				SqlExpressionGroup e=Cnd.exps("dept_id","in",ksuser).or("classg","in",ksuser).or("id","in",ksuser);
				cnd.and(e);
			}
			if(role.length()>0) {
				cnd.and("id", "in", exarrangeService.queryRoleUser(role));
			}
			List<User> users=userService.query("id", cnd);
			if(users==null || users.size()==0)return Result.error("没有指定的考生");
			//========找题目==========================================
			String ksid=exarrange.getKsid();
			TableDataInfo tdinfo=papertplService.tableList(1,null,Cnd.where("ksid", "=", ksid),"qtid","asc","qdb|qdbkb|qtype");
			int n=(int)tdinfo.getTotal();
			//========考试信息================================
			Paperdef paperdef=paperdefService.fetch(ksid);
			
			//==========为每人抽题组卷================
			for(User u:users){
				String uid=u.getId();
				//exarrange.setKsid(ksid);
	            exarrange.setUid(uid);
	            //exarrange.setEndtime(paperdef.getEndtime());
	            //exarrange.setStarttime(paperdef.getStarttime());
	            exarrange.setStatus(0);
				exarrange.setUdtime(0);
				//此处应当改进：创建考试任务时指定科目，设置试卷模板时，限定科目及知识点，
				// tpl=(Papertpl) tdinfo.getRows().get(0);
				exarrange.setKmid(paperdef.getKmid());
	            //=========================
				// 抽题 begin
				//=====================
				Paper paper=new Paper();
				paper.setKsid(ksid);
				paper.setName(paperdef.getName());
				paper.setStarttime(paperdef.getStarttime());
				paper.setEndtime(paperdef.getEndtime());
				paper.setDuration(paperdef.getDuration());
				paper.setNojj(paperdef.getNojj());
				paper.setTotalScore(paperdef.getTotalScore());
				paper.setPassScore(paperdef.getPassScore());
				
				String allqids="";
				String allqscores="";
				float sumqscores=0;
				NutMap qtidmap=new NutMap();//题型map
				NutMap qidmap=new NutMap();//题号map
				int total=0;
				int oldqtid=0;
				for (int i=0;i<n;i++){//不同知识点的题号、题数、分
					Papertpl tpl=(Papertpl) tdinfo.getRows().get(i);
					int qtid=tpl.getQtid();
					
					if(qtid!=oldqtid) {
						if(oldqtid!=0){
							NutMap qtidmap2=new NutMap();//题号map
							allqids=allqids.substring(1);
							allqscores=allqscores.substring(1);
							qtidmap2.addv("qids", allqids);
							qtidmap2.addv("qscores", allqscores);
							qtidmap2.addv("qscore", sumqscores);
							Qtype qtype=qtypeService.fetch(oldqtid);
							qtidmap2.addv("qname", qtype.getName());
							NutMap t2=new NutMap();
							t2.putAll(qtidmap2);
							qtidmap.addv(oldqtid+"", t2);
							total+=allqids.split(",").length;
							qidmap.clear();allqids="";allqscores="";sumqscores=0;
							oldqtid=qtid;
						}else oldqtid=qtid;
					}
					float score=tpl.getScore();
					int qnum=tpl.getQnum();
					String qids=tpl.getQids();

					if(qids.split(",").length>qnum){//需要抽题
						qids=StringUtils.getRandNdata(qids, qnum);
					}
					allqids+=","+qids;
					String[] qidsarr=qids.split(",");
					for(int j=0;j<qidsarr.length;j++){
						allqscores+=","+score;// 
						sumqscores+=score;
					}
					
				}
				NutMap qtidmap2=new NutMap();//题号map
				allqids=allqids.substring(1);
				allqscores=allqscores.substring(1);
				qtidmap2.addv("qids", allqids);
				qtidmap2.addv("qscores", allqscores);
				qtidmap2.addv("qscore", sumqscores);
				Qtype qtype=qtypeService.fetch(oldqtid);
				qtidmap2.addv("qname", qtype.getName());
				NutMap t2=new NutMap();
				t2.putAll(qtidmap2);
				qtidmap.addv(oldqtid+"", t2);
				total+=allqids.split(",").length;
				qidmap.clear();allqids="";allqscores="";sumqscores=0;
				oldqtid=0;
				
				NutMap t=new NutMap();
				t.putAll(qtidmap);
				paper.setQtidmap(t);				
				qtidmap.clear();

				paper.setTotal(total);
				exarrange.setPaperdata(Json.toJson(paper));
				//=========================
				// 抽题 end
				//=====================
				
				
				try{
				exarrangeService.insert(exarrange);
				Mytask task=new Mytask();
				task.setKsid(ksid);
				task.setName(paperdef.getName());
				task.setIntro(paperdef.getRemark());
				task.setUid(uid);
				task.setStarttime(paperdef.getStarttime());
				task.setEndtime(paperdef.getEndtime());
				task.setEntryurl("exam/exarrange/check");
				
				mytaskService.insert(task);
				} catch (Exception e) {
					log.debug("\r\n生成【"+uid+"】的试卷失败:"+e.getMessage());
				}
			}
			
			return Result.success("system.success");
		} catch (Exception e) {
			log.debug("\r\n"+e.getMessage());
			return Result.error("system.error");
		}
	}
	

	/**
	 * 删除试卷
	 * @param id
	 * @param req
	 * @return
	 */
	@At("/delp/?")
	@Ok("json")
	//@RequiresPermissions("exam:exarrange:remove")
	@Slog(tag ="删除试卷", after= "删除指定考试的试卷:${args[0]}")
	public Object delpaper(String id, HttpServletRequest req) {
		try {
			exarrangeService.delete(Cnd.where("ksid","=",id));
			return Result.success("system.success");
		} catch (Exception e) {
			return Result.error("system.error");
		}
	}
	/**
	 * 修改排考抽题
	 */
	@At("/edit/?")
	@Ok("th:/exam/exarrange/edit.html")
	public void edit(String id, HttpServletRequest req) {
		Exarrange exarrange = exarrangeService.fetch(id);
		req.setAttribute("exarrange",exarrange);
	}

    /**
     * 详情排考抽题
     */
    @At("/detail/?")
    @Ok("th:/exam/exarrange/detail.html")
    public void detail(String id, HttpServletRequest req) {
		Exarrange exarrange = exarrangeService.fetch(id);
        req.setAttribute("exarrange",exarrange);
    }

    /**
	 * 修改保存排考抽题
	 */
	@At
	@POST
	@Ok("json")
	@RequiresPermissions("exam:exarrange:edit")
	@Slog(tag="排考抽题", after="修改保存排考抽题")
	public Object editDo(@Param("..") Exarrange exarrange,HttpServletRequest req) {
		try {
			if(Lang.isNotEmpty(exarrange)){

				exarrangeService.update(exarrange);
			}
			return Result.success("system.success");
		} catch (Exception e) {
			return Result.error("system.error");
		}
	}

	/**
	 * 删除排考抽题
	 */
	@At("/remove")
	@Ok("json")
	@RequiresPermissions("exam:exarrange:remove")
	@Slog(tag ="排考抽题", after= "删除排考抽题:${array2str(args[0])}")
	public Object remove(@Param("ids")String[] ids, HttpServletRequest req) {
		try {
			exarrangeService.delete(ids);
			//需增加关联批量删除
			//mytaskService.delete(Cnd.where("));
			return Result.success("system.success");
		} catch (Exception e) {
			return Result.error("system.error");
		}
	}
	@At
	@POST
	@Ok("json")
	@Slog(tag="提交源码", after="保存提交的源码")
	public Object submitCode(@Param("..") Solution sol,@Param("source") String source,HttpServletRequest req) {
		Integer solid=0;
		try {
			if(Lang.isNotEmpty(sol)){
				//Date dt_prevSubmit = (Date)Mvcs.getHttpSession().getAttribute("session_submit");
				Date dt = new Date(); 
				User user = ShiroUtils.getSysUser();
				/*if(dt_prevSubmit!=null){
                    long d=dt.getTime()-dt_prevSubmit.getTime();
					if(d<15000){
                        log.error(d+",系统不允许在15秒内再次提交代码");
						return Result.error(user.getId()+",系统不允许在15秒内再次提交代码");
					}
				}*/
				
				Base64 base64 = new Base64();
				String source2=new String(base64.decode(source), "UTF-8");
				//int problemid=sol.getProblemId();
				//Question quest=questionService.fetch(problemid);
				//sol.setProblemId(Integer.parseInt(quest.getAnsI()));//acm中对应的题号及测试数据编号
				sol.setUid(user.getId());				
				sol.setCodeLength(source2.length());
				sol.setSubmitDate(new Date());
				sol.setMemory(0);
				sol.setTime(0);
				sol.setContestId(0);
				sol.setTestcase(0);
				sol.setVerdict(1);

				Solution s=solutionService.insert(sol);
				SolutionSource ss=new SolutionSource();
				solid=s.getSolutionId();
				ss.setSolutionId(solid);				
				ss.setSource(source2);
				solutionSourceService.insert(ss);
				
				Mvcs.getHttpSession().setAttribute("session_submit", dt);
				//========================================================
				String judger_ip =Globals.getConfig("OJ_JUDGER_IP");
				Integer judger_port = Integer.valueOf(Globals.getConfig("OJ_JUDGER_PORT")).intValue();
				OJSocket.JudgeRequest(judger_ip, judger_port, s.getSolutionId());
			}
			return Result.success(solid+"");
		} catch (Exception e) {
			return Result.error(e.getMessage());
		}
	}
	@At
	@POST
	@Ok("json")
	@Slog(tag="交卷", after="交卷完成：${args[0]}")
	public Object saveScores(@Param("id")Integer id,@Param("data") String obs,HttpServletRequest req) {
		Exarrange ex= exarrangeService.fetch(id);
		String ksid=ex.getKsid();
		String uid=ex.getUid();
		try {
			List<Question> qlist=Json.fromJsonAsList(Question.class, obs);//id,qscore,qans
			//Map<Integer,Question> ansmap=qlist.stream().collect(Collectors.toMap(Question::getId, Function.identity(), (key1, key2) -> key2));
			Map<Integer,String> ansmap=qlist.stream().collect(Collectors.toMap(Question::getId, Question::getQans, (key1, key2) -> key2));

			
			Paper paper=Json.fromJson(Paper.class, ex.getPaperdata());
			NutMap qtidmap= paper.getQtidmap();
			NutMap qtidmap2= new NutMap();
			
			NutMap qtscoremap=new NutMap();
			for(String key:qtidmap.keySet()){//一种题型/大题
				NutMap map=(NutMap)qtidmap.get(key);
				NutMap map2= new NutMap();
				int qtid=Integer.parseInt(key);
				String qscores=map.getString("qscores");//
				String qids=map.getString("qids");
				
				map2.addv("qids", qids);
				map2.addv("qscores", qscores);
				map2.addv("qname", map.getString("qname"));
				map2.addv("qscore", map.getFloat("qscore"));
				String qans="",stuans="",stuscore="";
				
				List<Question> qlistbyqt=questionService.query("^(id|qtid|qans)$",Cnd.where("id","in",qids).asc("instr(',"+qids+",',concat(',',id,','))"));
				int i=0;float sumscore=0;
				String[] stdscores=qscores.split(",");
				for(Question question:qlistbyqt){//每小题
					float stdscore=Float.parseFloat( stdscores[i++]);
					int qid=question.getId();
					
					if(qtid<5){//客观题，前端提交考生答案
						String stdans=question.getQans();
						//qans+=","+stdans;
						//Question stuquestion=ansmap.get(qid);
						//String stans="";
						//if(stuquestion!=null) {
						String stans=ansmap.get(qid);//stuquestion.getQans();
						if(stans==null){
							stuscore+=",0";
							stuans+=",-";
						}else{
							stuans+=","+stans;
							if( stans.equalsIgnoreCase(stdans)) {
								sumscore+=stdscore;
								stuscore+=","+stdscore;
							}else stuscore+=",0";
						}
					}else{//操作题，通过其它方式已提交考生答案

						//Question quest=questionService.fetch(qid);
						//int problemId=Integer.parseInt(quest.getAnsI());//acm中对应的题号及测试数据编号
						//可能多次提交，取最后一次
						Solution sol= solutionService.fetch(Cnd.where("ksid","=",ksid).and("uid","=",uid).and("problemId","=",qid).limit(1,1).desc("solutionId"));
						if(sol!=null){
							String srccode=solutionSourceService.fetch(sol.getSolutionId()).getSource();
							srccode=srccode.replace(">", "&gt;").replace("<", "&lt;");
							srccode=srccode.replace(",", "，");
							srccode="<pre><code>"+srccode+"</code></pre>";
							int verdict=sol.getVerdict();
							float sc1=0;
							if(verdict==5){
								sc1=stdscore;
							}else if(verdict==10){
								sc1=Math.round(stdscore*9f)/10;
							}
							
							
							String result=Globals.verdicts[verdict];
							String stans="<p><b><span class=\"tscore2\">&nbsp;&nbsp;&nbsp;&nbsp;评阅结果：</span></b></p>";
							stans+="<p><table border=\"1\" cellspacing=\"0\">";
							stans+="<tr>";
							stans+="<th style=\"min-width:60%\" scope=\"col\"><span class=\"tscore2\">考点内容</span></th>";
							stans+="<th style=\"min-width:20%\" scope=\"col\"><span class=\"tscore2\">分值</span></th>";
							stans+="<th style=\"min-width:20%\" scope=\"col\"><span class=\"tscore2\">得分</span></th>";
							
							stans+="</tr>";
							stans+="<tr><td><span class=\"ti\">"+srccode+"<br>"+result+"</span></td>";
							stans+="<td><span class=\"ti\">"+stdscore+"</span></td>";
							stans+="<td><span class=\"ti\">"+sc1+"</span></td>";
							stans+="</tr></table></p>";
							stuans+=","+stans;
							sumscore+=sc1;
							stuscore+=","+sc1;
						}
						else{
							String srccode="";
							float sc1=0;
							String stans="<p><b><span class=\"tscore2\">&nbsp;&nbsp;&nbsp;&nbsp;评阅结果：</span></b></p>";
							stans+="<p><table border=\"1\" cellspacing=\"0\"><tr>";
							stans+="<th style=\"min-width:60%\" scope=\"col\"><span class=\"tscore2\">考点内容</span></th>";
							stans+="<th style=\"min-width:20%\" scope=\"col\"><span class=\"tscore2\">分值</span></th>";
							stans+="<th style=\"min-width:20%\" scope=\"col\"><span class=\"tscore2\">得分</span></th>";
							stans+="</tr>";
							stans+="<tr><td><span class=\"ti\"><br>未提交代码</span></td>";
							stans+="<td><span class=\"ti\">"+stdscore+"</span></td>";
							stans+="<td><span class=\"ti\">0</span></td>";
							stans+="</tr></table></p>";
							stuans+=","+stans;
							sumscore+=sc1;
							stuscore+=","+sc1;
						}
					}
					//}else stuscore+=",0";
					
					//question.setQscore(Float.parseFloat( idscoremap.get(question.getId()+"").toString()));
					//question.setQscore();
				}
				qtscoremap.addv(key, sumscore);
				//map2.addv("qans", qans.substring(1));
				map2.addv("stuans", stuans.substring(1));
				map2.addv("stuscore", stuscore.substring(1));
				map2.addv("score",sumscore);
				qtidmap2.addv(key, map2);
			}
			//=======入库==========================
			Scores score=new Scores();
			float stuScore=0;int k=1;
			for(String key:qtscoremap.keySet()) {
				float onescore=qtscoremap.getFloat(key);
				stuScore+=onescore;
				switch(k){
					case 1:score.setScore1(onescore);break;
					case 2:score.setScore2(onescore);break;
					case 3:score.setScore3(onescore);break;
					case 4:score.setScore4(onescore);break;
					case 5:score.setScore5(onescore);break;
					case 6:score.setScore6(onescore);break;
					case 7:score.setScore7(onescore);break;
				}
				k++;
			}
			paper.setStuScore(stuScore);
			paper.setQtidmap(qtidmap2);
			//======试卷更新================
			String anspaper=Json.toJson(paper);
			//ex.setAnsdata(anspaper);//存吗？
			Date date=new Date();
			ex.setJjtime(date);
			ex.setStatus(8);
			exarrangeService.updateIgnoreNull(ex);
			//======成绩入库=================
			
			score.setJjtime(date);
			score.setKsid(ksid);
			score.setKmid(ex.getKmid());
			score.setPaperdata(anspaper);
			score.setUid(uid);
			score.setScore(stuScore);
			scoresService.insert(score);
			//mytaskService.update(Chain.make("status", 2), Cnd.where("ksid", "=", ex.getKsid()).and("uid", "=", ex.getUid()));
			//==============================================
			Paperdef paperdef=paperdefService.fetch(ex.getKsid());
			int kstype=paperdef.getKstype();
			//if(paperdef.isShowkey()) return Result.success("交卷成功！你的成绩是：<b style='color:#f00'>"+stuScore+"</b>");
			//else return Result.success("交卷成功！");
			Scores myscore=scoresService.fetch(Cnd.where("ksid","=",ksid).and("uid","=",uid));
			if(kstype==2) return Result.success("exam/scores/detail/"+myscore.getId());
			else  return Result.success("login/kdlogout");
			//return Result.success(myscore.getScore()+"");
		} catch (Exception e) {
			ex.setJjtime(new Date());
			ex.setStatus(9);
			exarrangeService.updateIgnoreNull(ex);
			return Result.error("交卷时遇到错误:\r\n"+e.getMessage());
		}
	}
	/**
	 * 心跳缓存
	 * @param id
	 * @param token
	 * @param cdata
	 * @param req
	 * @return
	 */
	@At("/saveHeartB")
	@POST
	@Ok("json")
	//@RequiresPermissions("exam:exarrange:edit")
	public Object saveHeartB(@Param("id") Integer id,
			@Param("token")String token,@Param("cdata")String cdata,
			HttpServletRequest req){
		try{
			Exarrange exarr=exarrangeService.fetch(id);
			//Date sntime=exarr.getSignintime();
			//Date now=new Date();
			//int d=new Double(DateUtils.getDistanceOfTwoDate(sntime, now, "m")).intValue();
			//int udtime=exarr.getUdtime();
			//exarr.setUdtime(udtime+t);//有bug：考生不断刷新浏览器会导致时间无穷无尽
			int d=exarr.getUdtime()+1;//断网无法计时.机器故障等原因停止考试，不计时
			exarr.setUdtime(d);
			exarrangeService.updateIgnoreNull(exarr);
			//ehcache 答题
			if(token!=null && cdata!=null) MyCache.addCache(token, cdata);
			return Result.success("");
		}catch(Exception e){
			return Result.error(e.getMessage());
		}
	}
	@At("/loadCache")
	@POST
	@Ok("json")
	//@RequiresPermissions("exam:exarrange:edit")
	public Object loadCache(@Param("token") String token,
			HttpServletRequest req){
		try{			
			//ehcache 答题
			Object cdata=MyCache.getCache(token);
			return Result.success(cdata.toString());
		}catch(Exception e){
			return Result.error(e.getMessage());
		}
	}
/*	考生管理  */
    @At
    @Ok("th:/exam/exarrange/kduser.html")
    public void kduser(HttpServletRequest req) {

    }
    /**
     * 查询用户列表
     */
    @At
    @Ok("json")
    public Object listuser(@Param("pageNum")Integer pageNum,
                       @Param("pageSize")Integer pageSize,
                       @Param("id") String id,//用户查询
                       @Param("orderByColumn") String orderByColumn,
                       @Param("isAsc") String isAsc,
                       HttpServletRequest req) {
        Cnd cnd = Cnd.NEW();
        if (!Strings.isBlank(id)) {
            cnd.and("id", "like", "%" + id + "%").or("user_name", "like", "%" + id + "%");
        }
        User user=ShiroUtils.getSysUser();
        String deptId=user.getDeptId();
        if (!Strings.isBlank(deptId)) {
            cnd.and("deptId", "=", deptId);
        }
        return userService.tableList(pageNum, pageSize, cnd, orderByColumn, isAsc, "dept");
    }
    /**
     * 删除用户
     */
    @At("/kdremove")
    @Ok("json")
    @RequiresPermissions("exam:exarrange:remove")
    @Slog(tag = "考点用户管理", after = "删除用户:${array2str(args[0])}")
    public Object kdremove(@Param("ids") String[] ids, HttpServletRequest req) {
        try {
            userService.delete(ids);
            return Result.success("system.success");
        } catch (Exception e) {
            return Result.error("system.error");
        }
    }
	/**
	 * 新增考生
	 */
	@At("/kdadd")
	@Ok("th:/exam/exarrange/kdadduser.html")
	
	public void adduser(HttpServletRequest req) {
		User user=ShiroUtils.getSysUser();
		req.setAttribute("deptId", user.getDeptId());
		Paperdef paperdef= paperdefService.fetch(Cnd.where("status","=",1));
		req.setAttribute("paperdef", paperdef);
	}
	/**
	 * 修改考生
	 */
	@At("/kdedit/?")
	@Ok("th:/exam/exarrange/kdedituser.html")
	public void edituser(String id,HttpServletRequest req) {
		User user=userService.fetch(id);
		req.setAttribute("user", user);
		Paperdef paperdef= paperdefService.fetch(Cnd.where("status","=",1));
		req.setAttribute("paperdef", paperdef);
	}
    /**
     * 由考点新增保存用户
     */

    @RequiresPermissions("sys:user:add")
    @At
    @POST
    @Ok("json")
    @Slog(tag = "考点新增考生", after = "新增保存用户管理id=${args[0].id}")
    public Object kdaddDo(@Param("..") User user,  HttpServletRequest req) {
        try {
        	//======新考生+role授权=====================
            userService.insert(user);         
            return Result.success("system.success");
        } catch (Exception e) {
        	log.debug(e.getMessage());
            return Result.error(e instanceof ErrorException ? e.getMessage() : "system.error");
        }
    }
    /**
     * 考生uid登录时，抽题生成试卷
     * 如果重考，则抽题尽量不与前一套同题。
     * 该方法仅限只有一个开放(status=1)的考试任务paperdef
     * @param uid
     * @return
     */
    public Result makepaper(String uid,NutMap oldmap) {
        try {
            //======为其抽题==========================
            Paperdef paperdef=paperdefService.fetch(Cnd.where("status","=",1));
            String ksid=paperdef.getId();
			
            Exarrange exarrange=new Exarrange();
            exarrange.setKsid(ksid);
            exarrange.setUid(uid);
            exarrange.setEndtime(paperdef.getEndtime());
            exarrange.setStarttime(paperdef.getStarttime());
            exarrange.setStatus(0);
			exarrange.setUdtime(0);
            //=========================
            TableDataInfo tdinfo=papertplService.tableList(1,null,Cnd.where("ksid", "=", ksid),"qtid","asc","qdb|qdbkb|qtype");
			int n=(int)tdinfo.getTotal();
			//=====================
			Paper paper=new Paper();
			paper.setKsid(ksid);
			paper.setName(paperdef.getName());
			paper.setStarttime(paperdef.getStarttime());
			paper.setEndtime(paperdef.getEndtime());
			paper.setDuration(paperdef.getDuration());
			paper.setNojj(paperdef.getNojj());
			paper.setTotalScore(paperdef.getTotalScore());
			paper.setPassScore(paperdef.getPassScore());
			
			String allqids="";
			String allqscores="";
			float sumqscores=0;
			NutMap qtidmap=new NutMap();//题型map
			NutMap qidmap=new NutMap();//题号map
			int total=0;
			int oldqtid=0;
			for (int i=0;i<n;i++){//不同知识点的题号、题数、分
				Papertpl tpl=(Papertpl) tdinfo.getRows().get(i);
				int qtid=tpl.getQtid();
				
				if(qtid!=oldqtid) {
					if(oldqtid!=0){
						NutMap qtidmap2=new NutMap();//题号map
						allqids=allqids.substring(1);
						allqscores=allqscores.substring(1);
						qtidmap2.addv("qids", allqids);
						qtidmap2.addv("qscores", allqscores);
						qtidmap2.addv("qscore", sumqscores);
						Qtype qtype=qtypeService.fetch(oldqtid);
						qtidmap2.addv("qname", qtype.getName());
						NutMap t2=new NutMap();
						t2.putAll(qtidmap2);
						qtidmap.addv(oldqtid+"", t2);
						total+=allqids.split(",").length;
						qidmap.clear();allqids="";allqscores="";sumqscores=0;
						oldqtid=qtid;
					}else oldqtid=qtid;
				}
				float score=tpl.getScore();
				int qnum=tpl.getQnum();
				String qids=tpl.getQids();
				if(oldmap!=null){
					NutMap oldmap2=(NutMap)oldmap.get(qtid+"");
					String oldqids=oldmap2.getString("qids");
					if(qids.split(",").length-oldqids.split(",").length>qnum){//题目数量足量，可以去重
						qids=StringUtils.delNSubString(qids, oldqids);
					}
				}
				if(qids.split(",").length>qnum){//需要抽题
					qids=StringUtils.getRandNdata(qids, qnum);
				}
				allqids+=","+qids;
				String[] qidsarr=qids.split(",");
				for(int j=0;j<qidsarr.length;j++){
					allqscores+=","+score;// 
					sumqscores+=score;
				}
				
			}
			NutMap qtidmap2=new NutMap();//题号map
			allqids=allqids.substring(1);
			allqscores=allqscores.substring(1);
			qtidmap2.addv("qids", allqids);
			qtidmap2.addv("qscores", allqscores);
			qtidmap2.addv("qscore", sumqscores);
			Qtype qtype=qtypeService.fetch(oldqtid);
			qtidmap2.addv("qname", qtype.getName());
			NutMap t2=new NutMap();
			t2.putAll(qtidmap2);
			qtidmap.addv(oldqtid+"", t2);
			total+=allqids.split(",").length;
			qidmap.clear();allqids="";allqscores="";sumqscores=0;
			oldqtid=0;
			
			NutMap t=new NutMap();
			t.putAll(qtidmap);
			paper.setQtidmap(t);				
			qtidmap.clear();

			paper.setTotal(total);
			Papertpl tpl=(Papertpl) tdinfo.getRows().get(0);
			exarrange.setKmid(tpl.getQdbid());
			exarrange.setPaperdata(Json.toJson(paper));
			try{
			exarrangeService.insert(exarrange);
			} catch (Exception e) {
				return Result.error("\r\n生成【"+uid+"】的试卷失败:"+e.getMessage());
			}
            //===========================================
            return Result.success("system.success");
        } catch (Exception e) {
        	log.debug(e.getMessage());
            return Result.error("\r\n生成【"+uid+"】的试卷失败:"+e.getMessage());
        }
    }
    
    /**
     * 由考点修改保存用户
     */

    @RequiresPermissions("sys:user:edit")
    @At
    @POST
    @Ok("json")
    @Slog(tag = "考点修改考生", after = "修改保存用户管理id=${args[0].id}")
    public Object kdeditDo(@Param("..") User user,  HttpServletRequest req) {
    	try {
          if (Lang.isNotEmpty(user)) {
              userService.update(user);
          }
          return Result.success("system.success");
      } catch (Exception e) {
          return Result.error(e instanceof ErrorException ? e.getMessage() : "system.error");
      }
    }
}
